﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace B121 {
    public static class AccessData {
        /// <summary>
        /// Converts a string to an int if possible, otherwise throws an exception
        /// </summary>
        /// <param name="value">String to parse</param>
        /// <returns>The string as an int</returns>
        public static int TryToParseInt(string value) {
            int number;

            if (int.TryParse(value, out number)) {
                return number; // Could be parsed
            } else {
                throw new ArgumentException("Couldn't convert the value to an integer!");
            }
        }

        /// <summary>
        /// Converts a decimal to an int if possible, otherwise throws an exception
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static int TryToParseInt(decimal value) {
            return TryToParseInt(value.ToString());
        }

        /// <summary>
        /// Reads all profiles from the specified folder
        /// </summary>
        /// <param name="profilesPath">The path to read profiles from</param>
        /// <returns>A list of profiles and their respective paths</returns>
        public static List<string[]> ReadAllProfiles(string profilesPath) {
            List<string[]> profiles = new List<string[]>();

            if (!Directory.Exists(profilesPath)) {
                Directory.CreateDirectory(profilesPath);
            } else {
                foreach (string dir in Directory.GetDirectories(profilesPath)) { // Read all profiles
                    profiles.Add(new string[] {
                    dir.Split(Path.DirectorySeparatorChar).Last(), // Read folder (profile) name
                    dir // Read path
                });
                }
            }


            return profiles;
        }

        /// <summary>
        /// Reads all containers from a profile
        /// </summary>
        /// <param name="path">Path to read from</param>
        /// <param name="containers">out parameter to store containers in</param>
        /// <returns>True if all read okay, otherwise false</returns>
        public static bool ReadAllContainersFromProfile(string path, out List<ContainerClass> containers) {
            containers = new List<ContainerClass>();

            try { // We might encounter an error
                using (StreamReader reader = new StreamReader(path + Path.DirectorySeparatorChar + "Containers.txt")) {
                    while (!reader.EndOfStream) { // Read all lines
                        string[] str = reader.ReadLine().Split('|'); // Temp string

                        string name = str[0];
                        int width = TryToParseInt(str[1]);
                        int length = TryToParseInt(str[2]);
                        int height = TryToParseInt(str[3]);
                        int maxWeight = TryToParseInt(str[4]);

                        containers.Add(new ContainerClass(name, width, length, height, maxWeight));
                    }
                }
            } catch (ArgumentException) {
                return false; // Could not write
            } catch (IOException) {
                return false; // Could not write
            }
            return true;
        }

        /// <summary>
        /// Reads all items from a profile
        /// </summary>
        /// <param name="path">Path to read from</param>
        /// <param name="containers">out parameter to store items in</param>
        /// <returns>True if all read okay, otherwise false</returns>
        public static bool ReadAllItemsFromProfile(string path, out List<ItemClass> items) {
            items = new List<ItemClass>();

            try { // We might encounter an error
                using (StreamReader reader = new StreamReader(path + Path.DirectorySeparatorChar + "Items.txt")) {

                    while (!reader.EndOfStream) { // Read all lines
                        string[] str = reader.ReadLine().Split('|'); // Temp string

                        string name = str[0];
                        int length = TryToParseInt(str[1]);
                        int width = TryToParseInt(str[2]);
                        int height = TryToParseInt(str[3]);
                        int weight = TryToParseInt(str[4]);

                        items.Add(new ItemClass(name, length, width, height, weight));
                    }
                }
            } catch (ArgumentException) {
                return false; // Could not write
            } catch (IOException) {
                return false; // Could not write
            }
            return true;
        }

        /// <summary>
        /// Writes all containers
        /// </summary>
        /// <param name="path">Profile to write </param>
        /// <param name="containers">Containers to write</param>
        /// <returns>True if succeeded, otherwise false</returns>
        public static bool WriteAllContainers(string path, List<ContainerClass> containers) {
            CreateDirIfItDoesNotExist(path);

            try { // We might encounter an error
                using (StreamWriter writer = new StreamWriter(path + Path.DirectorySeparatorChar + "Containers.txt")) {
                    foreach (ContainerClass container in containers) {
                        writer.WriteLine(container.Name + "|" +
                            container.X + "|" +
                            container.Y + "|" +
                            container.Z + "|" +
                            container.MaxWeight);
                    }
                }
            } catch (ArgumentException) {
                return false; // Could not write
            } catch (IOException) {
                return false; // Could not write
            }

            return true;
        }

        /// <summary>
        /// Writes all items
        /// </summary>
        /// <param name="path">Profile to write</param>
        /// <param name="items">Items to write</param>
        /// <returns>True if succeeded, otherwise false</returns>
        public static bool WriteAllItems(string path, List<ItemClass> items) {
            CreateDirIfItDoesNotExist(path);

            try { // We might encounter an error
                using (StreamWriter writer = new StreamWriter(path + Path.DirectorySeparatorChar + "Items.txt")) {
                    foreach (ItemClass item in items) {
                        writer.WriteLine(item.Name + "|" +
                            item.X + "|" +
                            item.Y + "|" +
                            item.Z + "|" +
                            item.Weight);
                    }
                }
            } catch (ArgumentException) {
                return false; // Could not write
            } catch (IOException) {
                return false; // Could not write
            }

            return true;
        }

        /// <summary>
        /// Creates a directory if it does not exist
        /// </summary>
        /// <param name="path">Directory to check/create</param>
        /// <param name="fileName"></param>
        private static void CreateDirIfItDoesNotExist(string path) {
            if (!Directory.Exists(path)) {
                Directory.CreateDirectory(path); // Create the directory if it does not exist
            }
        }
    }
}
